package com.atguigu.guli.service.ucenter.controller.api;

import com.atguigu.guli.common.util.HttpClientUtils;
import com.atguigu.guli.service.base.exception.GuliException;
import com.atguigu.guli.service.base.helper.JwtHelper;
import com.atguigu.guli.service.base.helper.JwtInfo;
import com.atguigu.guli.service.base.result.R;
import com.atguigu.guli.service.base.result.ResultCodeEnum;
import com.atguigu.guli.service.ucenter.entity.Member;
import com.atguigu.guli.service.ucenter.service.MemberService;
import com.atguigu.guli.service.ucenter.service.feign.OssFileService;
import com.atguigu.guli.service.ucenter.util.UcenterProperties;
import com.google.gson.Gson;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.UUID;

//@CrossOrigin
@Controller//注意这里没有配置 @RestController
@RequestMapping("/api/ucenter/wx")
@Slf4j
public class ApiWxController {
    @Autowired
    private UcenterProperties ucenterProperties;
    @Autowired
    private MemberService memberService;
    @Autowired
    private OssFileService ossFileService;

    @GetMapping("login")
    public String genQrConnect(HttpSession session){

        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";

        //处理回调uri
        String redirectUri = null;
        try {
            redirectUri = URLEncoder.encode(ucenterProperties.getRedirectUri(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new GuliException(ResultCodeEnum.URL_ENCODE_ERROR);
        }

        //生成state
        String state = UUID.randomUUID().toString();
        System.out.println("wx_open_state = " + state);
        session.setAttribute("wx_open_state",state);

        String qrcodeUrl = String.format(
                baseUrl,
                ucenterProperties.getAppId(),
                redirectUri,
                state
        );

        return "redirect:" + qrcodeUrl;
    }

    @ApiOperation("微信回调")
    @GetMapping("callback")
    public String callback(String code, String state, HttpSession session){
        System.out.println("code = " + code);
        System.out.println("state = " + state);

        if (StringUtils.isEmpty(code) || StringUtils.isEmpty(state)){
            log.error("非法回调请求");
            throw new GuliException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
        }

        String sessionState = (String)session.getAttribute("wx_open_state");
        if (!state.equals(sessionState)){
            log.error("非法回调请求");
            throw new GuliException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
        }

        //携带授权临时票据code，和appid以及appsecret请求access_token
        String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=" + ucenterProperties.getAppId() +
                "&secret=" + ucenterProperties.getAppSecret() +
                "&code=" + code +
                "&grant_type=authorization_code";

        HttpClientUtils clientUtils = new HttpClientUtils(accessTokenUrl);

        clientUtils.setHttps(true);
        String result = "";
        try {
            clientUtils.get();
            result = clientUtils.getContent();
            System.out.println(result);
        } catch (Exception e) {
            throw new GuliException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
        }

        Gson gson = new Gson();
        HashMap<String,Object> resultMap = gson.fromJson(result, HashMap.class);


        String accessToken =(String) resultMap.get("access_token");

        //微信获取access_token响应失败
        Object errcode = resultMap.get("errcode");
        if (errcode != null){
            log.error("获取access_token失败 - " + "errmsg: " + (String)resultMap.get("errmsg") + ", errcode: " + (String)errcode);
            throw new GuliException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
        }

        //微信获取access_token响应成功
        String openid =(String) resultMap.get("openid");
//        String unionid =(String) resultMap.get("unionid");
        System.out.println("accessToken = " + accessToken);
        System.out.println("openid = " + openid); //不通用
//        System.out.println("unionid = " + unionid); //跨应用通用


        //根据access_token获取微信用户的基本信息
        //根据openid查询当前用户是否已经使用微信登录过该系统
        Member member = memberService.getByOpenid(openid);
        if (member == null){
            //插入数据
            String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=" + accessToken +
                    "&openid=" + openid;
            clientUtils = new HttpClientUtils(userInfoUrl);

            clientUtils.setHttps(true);
            String userInfoResult = "";
            try {
                clientUtils.get();
                userInfoResult = clientUtils.getContent();
                System.out.println(userInfoResult);
            } catch (Exception e) {
                throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
            }

            gson = new Gson();
            HashMap<String,Object> userInforesultMap = gson.fromJson(userInfoResult, HashMap.class);

            //获取用户信息响应失败
            errcode = userInforesultMap.get("errcode");
            if (errcode != null){
                log.error("获取用户信息失败 - " + "errmsg: " + (String)userInforesultMap.get("errmsg") + ", errcode: " + (String)errcode);
                throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
            }

            //获取用户信息成功，注册用户
            String nickname = (String) userInforesultMap.get("nickname");
            String headimgurl = (String) userInforesultMap.get("headimgurl");
            Double sex = (Double) userInforesultMap.get("sex");
            member = new Member();
            member.setOpenid(openid);
            member.setNickname(nickname);

//            member.setAvatar(headimgurl);
            R r = ossFileService.uploadFromUrl(headimgurl, "avatar");
            String url = (String)r.getData().get("url");
            member.setAvatar(url);

            member.setSex(sex.intValue());
            memberService.save(member);

        }/*else {
            //方法一：直接使用数据库中的数据
            //方法二:查询微信用户数据修改现有的数据
        }*/

        //生成JWT
        JwtInfo jwtInfo = new JwtInfo();
        jwtInfo.setId(member.getId());
        jwtInfo.setAvatar(member.getAvatar());
        jwtInfo.setNickname(member.getNickname());
        String token = JwtHelper.createToken(jwtInfo);

        //携带token跳转
        return "redirect:http://localhost:3000?token=" + token;
    }
}
